﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using Mitosoft.Definitions.Services;

namespace Mitosoft.Definitions.ViewModels
{
  /// <summary>
  /// Represents one directory view model containing other directories as children.
  /// </summary>
  public class IOViewModel : TreeViewItemViewModel
  {
    #region fields

    /// <summary>
    /// Represents <see cref="FullPath"/>
    /// </summary>
    protected string _fullPath;

    /// <summary>
    /// Represents <see cref="DirectoryService"/>
    /// </summary>
    protected IDirectoryService _directoryService;

    #endregion

    #region constructors

    /// <summary>
    /// Creates a new <see cref="IOViewModel"/> instance.
    /// </summary>
    /// <param name="fullPath">Represents <see cref="FullPath"/></param>
    /// <param name="parentDirectory">Represents the parent directory view model.</param>
    /// <param name="directoryService">Represents the service used to retrieve directories.</param>
    public IOViewModel(
      string fullPath, ITreeViewItemViewModel parentDirectory, IDirectoryService directoryService) 
      : base(parentDirectory, true)
    {
      _fullPath = fullPath;
      _directoryService = directoryService;
    }

    /// <summary>
    /// Destructor. Will run only if Dispose has not been called.
    /// </summary>
    ~IOViewModel()
    {
      Dispose(false);
    }

    #endregion

    #region properties

    /// <summary>
    /// Represents the service used to get directories.
    /// </summary>
    protected IDirectoryService DirectoryService
    {
      get { return _directoryService; }
      set { _directoryService = value; }
    }

    /// <summary>
    /// Gets or sets the full path name of THIS directory.
    /// </summary>
    public string FullPath
    {
      get { return _fullPath; }
      set
      {
        _fullPath = value;
        // ReSharper disable once ExplicitCallerInfoArgument
        HandlePropertyChanged("DisplayText");
      }
    }

    /// <summary>
    /// Gets the last part of <see cref="FullPath"/>
    /// Used to be displayed by the view.
    /// </summary>
    public new string DisplayText
    {
      get
      {
        return 
          Calculations.Calculations.GetLastPartOfFullPath(
            FullPath);
      }
    }

    #endregion

    #region methods

    /// <summary>
    /// Invoked when the child items need to be loaded on demand.
    /// Subclasses should override this to populate the Children collection.
    /// Only needed if the subclasses owns logically children.
    /// </summary>
    protected override void LoadChildren()
    {
      if (DirectoryService == null) return;

      var result = new ObservableCollection<ITreeViewItemViewModel>();
      
      List<string> topSubDirectories = DirectoryService.GetAllTopSubDirectories(FullPath);
      if (topSubDirectories != null)
      {
        foreach (string rootDirectory in topSubDirectories)
        {
          result.Add(
            new IOViewModel(
              rootDirectory, this, DirectoryService));
        }
      }

      Children = result;
    }

    /// <summary>
    /// Disposes this object.
    /// </summary>
    /// <param name="isDisposing">Represents whether this object is disposing.</param>
    protected override void Dispose(bool isDisposing)
    {
      if (_isDisposed) return;

      if (isDisposing)
      {
        #region dispose managed resources

        _fullPath = null;
        _directoryService = null;

        #endregion
      }
    }

    #endregion
  }
}
